package com.adds.lvds.security.acegi;

import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.AccessDecisionManager;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.authentication.InsufficientAuthenticationException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Service;

import com.adds.lvds.core.utils.PropertiesUtils;
import com.adds.lvds.security.dao.SysUserMapper;
import com.adds.lvds.security.model.SysCurrentUser;
import com.adds.lvds.security.model.SysResource;
import com.adds.lvds.security.service.SysResourceService;

/**
 * 自己实现的过滤用户请求类，也可以直接使用 FilterSecurityInterceptor
 * 
 * AbstractSecurityInterceptor有三个派生类：
 * FilterSecurityInterceptor，负责处理FilterInvocation，实现对URL资源的拦截。
 * MethodSecurityInterceptor，负责处理MethodInvocation，实现对方法调用的拦截。
 * AspectJSecurityInterceptor，负责处理JoinPoint，主要是用于对切面方法(AOP)调用的拦截。
 * 
 * 还可以直接使用注解对Action方法进行拦截，例如在方法上加：
 * 
 * @PreAuthorize("hasRole('ROLE_SUPER')") <!-- 用户是否拥有所请求资源的权限 -->
 * 
 * @author zhangjian 2017-11-19
 * @version 1.0v
 */
@Service
public class MyAccessDecisionManager implements AccessDecisionManager {

	@Autowired
	private SysUserMapper sysUserMapper;
	@Autowired
	private SysResourceService sysResourceService;

	public void decide(Authentication authentication, Object object,
			Collection<ConfigAttribute> configAttributes)
			throws AccessDeniedException, InsufficientAuthenticationException {
		// System.err.println(" ---------------  MyAccessDecisionManager --------------- ");
		if (configAttributes == null) {
			return;
		}
		// 所请求的资源拥有的权限(一个资源对多个权限)
		Iterator<ConfigAttribute> iterator = configAttributes.iterator();
		while (iterator.hasNext()) {
			ConfigAttribute configAttribute = iterator.next();
			// 访问所请求资源所需要的权限
			String needPermission = configAttribute.getAttribute();
			// 根据用户名获取用户权限
			String userName = null;
			Object principal = authentication.getPrincipal();
			if (principal instanceof UserDetails) {
				userName = ((UserDetails) principal).getUsername();
			} else {
				userName = principal.toString();
			}

			Map<String, Object> map = new HashMap<>();
			List<SysResource> rs = null;
			if (PropertiesUtils.findPropertiesKey("rootName").equals(userName)) {
				map.put("role_id", 1);
				rs = sysResourceService.querySysResourceByMap(map);
			} else {
				map.put("username", userName);
				SysCurrentUser users = this.sysUserMapper.getSysUserByMap(map);
				map.put("role_id", users.getRoleList().get(0).getId());
				rs = sysResourceService.querySysResourceByMap(map);
			}

			Set<GrantedAuthority> authSet = new HashSet<GrantedAuthority>();
			for (SysResource res : rs) {
				// TODO:ZZQ 用户可以访问的资源名称（或者说用户所拥有的权限） 注意：必须"ROLE_"开头
				// 关联代码：applicationContext-security.xml
				// 关联代码：com.huaxin.security.MySecurityMetadataSource#loadResourceDefine
				authSet.add(new SimpleGrantedAuthority("ROLE_"
						+ res.getResKey()));
			}
			for (GrantedAuthority ga : authSet) {
				if (needPermission.equals(ga.getAuthority())) {
					return;
				}
			}
		}
		// 没有权限
		throw new AccessDeniedException(" 没有权限访问！ ");
	}

	public boolean supports(ConfigAttribute attribute) {
		// TODO Auto-generated method stub
		return true;
	}

	public boolean supports(Class<?> clazz) {
		// TODO Auto-generated method stub
		return true;
	}

}